﻿using System.Collections.Generic;

namespace UniSender
{
    using Expando = Dictionary<string, object>;
    using IExpando = IDictionary<string, object>;
    using IValues = IDictionary<string, string>;
    using Values = Dictionary<string, string>;

    public class EmailConfig
    {
        public class Header
        {
            public const string
                ReplayTo = "Replay-To",
                Priority = "Priority";
        }

        private IValues headers = new Values();

        public virtual string Email { get; set; }

        public virtual string Sender { get; set; }

        public virtual string SenderEmail { get; set; }

        public virtual string Subject { get; set; }

        public virtual string Body { get; set; }

        public virtual long ListId { get; set; }

        public virtual string UserCampaingId { get; set; }

        public virtual IEmailAttachment[] Attachments { get; set; }

        public virtual string Lang { get; set; }

        public virtual bool? TrackRead { get; set; }

        public virtual bool? TrackLinks { get; set; }

        public virtual string Cc { get; set; }

        public virtual IValues Headers
        {
            get { return headers; }
            set { headers.Update(value); }
        }

        public virtual string ReplyTo
        {
            get {
                return headers.ContainsKey(Header.ReplayTo) ? 
                    headers[Header.ReplayTo] : 
                    null;
            }
            set
            {
                if (string.IsNullOrEmpty(value))
                    headers.Remove(Header.ReplayTo);
                else
                    headers[Header.ReplayTo] = value;
            }
        }

        public virtual EmailPriority? Priority
        {
            get
            {
                if (headers.ContainsKey(Header.Priority))
                    switch (headers[Header.Priority])
                    {
                        case "normal":
                            return EmailPriority.Normal;
                        case "urgent":
                            return EmailPriority.Urgent;
                        case "non-urgent":
                            return EmailPriority.NonUrgent;
                    }
                return null;
            }
            set
            {
                switch (value)
                {
                    case EmailPriority.Normal:
                        headers[Header.Priority] = "normal";
                        break;
                    case EmailPriority.Urgent:
                        headers[Header.Priority] = "urgent";
                        break;
                    case EmailPriority.NonUrgent:
                        headers[Header.Priority] = "non-urgent";
                        break;
                    default:
                        headers.Remove(Header.Priority);
                        break;
                }
            }
        }

        public virtual WrapType? WrapType { get; set; }

        public virtual ImagesAs? ImagesAs { get; set; }

        public virtual IExpando Serialize()
        {
            var args = new Expando();

            args["email"] = Email;
            args["sender_name"] = Sender;
            args["sender_email"] = SenderEmail;
            args["subject"] = Subject;
            args["body"] = Body;
            args["list_id"] = ListId;
            args["user_campaign_id"] = UserCampaingId;
            args["attachments"] = Attachments;
            args["lang"] = Lang;
            if (TrackRead != null)
                args["track_read"] = TrackRead.Value ? 1 : 0;
            if (TrackLinks != null)
                args["track_links"] = TrackLinks.Value ? 1 : 0;
            args["cc"] = Cc;
            args["headers"] = Headers;
            args["wrap_type"] = WrapType.Stringify();
            args["images_as"] = ImagesAs.Stringify();
            args["error_checking"] = 1;

            return args;
        }
    }
}
